'use strict'

process.chdir(__dirname)

const titbit=require('titbit')
const fs=require('fs')
const pg=require("pg")
const dbcfg=require("./dbconfig.js")
const wxkey=require('./wxkey.js')
const {httpcli}=require('gohttp')
const token=require('titbit-token')

try{
    fs.accessSync('./images')
}catch(err){
    fs.mkdirSync('./images')
}
let psql=new pg.Pool(dbcfg);
let cert_path='/usr/local/share'
const app=new titbit({
    //开启调试模式，会输出错误信息
    debug:true,
    globalLog:true,
    cert:`${cert_path}/abc.hiehie.top.pem`,
    key:`${cert_path}/abc.hiehie.top.key`
})

//添加路由
app.get('/',async c=>{
    c.send('ok')
})

/**---------------------------content路由--------------------------------------- */
//获取内容列表
app.get('/content',async c=>{
    let ret=await psql.query(`select * from content`)
    //等价于c.res.body=ret.rows
    c.send(ret.rows)
})
//获取具体内容
app.get('/content/:id',async c=>{
    let sqltext=`SELECT * FROM content WHERE id=$1`
    let r=await psql.query(sqltext,[c.param.id])
    if(r.rowCount===0){
        return c.status(404).send('content not found')
    }
    c.send(r.rows[0])
})
//创建内容
app.post('/content',async c=>{
    try{
        //提交的Body数据通过c.body获取
        let data = JSON.parse(c.body);

        let sqltext=`INSERT INTO `
                    +` content (id, add_time, detail, title, update_time) `
                    +` VALUES ($1, $2, $3, $4, $5)`;

        //生成唯一ID,随机字符串
        let id=c.helper.makeId()
        let tm=Date.now()
 
        let r = await psql.query(sqltext, [
            id, tm, data.detail, data.title, tm
        ])

        if(r.rowCount===0){
            return c.status(500).send('failed')
        }
        c.send(id)
    }catch(err){
        console.error(err)
        c.status(400).send('it is not json data')
    }
})
/**---------------------------content路由-END--------------------------------------- */

app.get('/upload',async c=>{
    //c.reply是响应对象，可写的流，
    //在HTTP、1.1中指向response，在HTTP、2中指向http2stream
    await c.helper.pipe('./upload.html',c.reply)
})

app.post('/upload',async c=>{
    //根据name获取文件对象
    let f=c.getFile('image')
    if(!f){
        return c.status(400).send('image not found')
    }
    //根据传入的原始文件名生成唯一文件名，主要使用f.filename的扩展名
    let fname=c.helper.makeName(f.filename)
    //移动文件到特定位置
    await c.moveFile(f,`./images/${fname}`)
    c.send(fname)

})

//任意参数
// app.get('/static/*',async c=>{
// })


//返回图片数据
app.get('/image/:name',async c=>{
    //c.param是一个对象，其中key值是路由参数的名称
    let imgname=c.param.name
    await c.helper.pipe(`./images/${imgname}`,c.reply)
})
let tok = new token({
    expires: 45,
    //必须是32位字符
    key: '1a2sz3dfr45tgvbhyu789mkljhbvcdew',

    //必须是16位字符
    iv: 'wgshxhsgwu890536'
})
app.get('/mp-login/:code',async c=>{
    let auth_url=`https://api.weixin.qq.com/sns/jscode2session`
                +`?appid=${wxkey.appid}`
                +`&secret=${wxkey.secret}`
                +`&js_code=${c.param.code}`
                +`&grant_type=authorization_code`
    let ret=await httpcli.get(auth_url)
                        .then(res=>{
                            return res.json()
                        })
    c.send(tok.make(ret))
})
app.get('/decrypt/:token',async c=>{
    c.send(tok.verify(c.param.token))
})
//运行在1234端口
app.run(1234)

/**
 * HTTP 消息头 content-type 指定了数据的类型（数据的格式）
 * Client                                   Server
 *    content-type描述的值                      根据content-type的值决定如何解析Body数据
 *    要和提交的Body数据格式一致。
 * content-type：
 * multipart/form-data;boundary=xxx  --------文件解析
 * text/*     -------------------------------文本类型
 * application/*  ---------------------------要看具体值，application/json也是文本类型
 * ......     -------------------------------每种类型如何处理是双方设计好的通信方式
 * 到WEB框架这一层面，则如何处理是开发框架设计好的，但通常都要遵循一个原则：
 *    允许开发者做自己的处理。
 * 在本框架范围内：
 *       multipart类型  c.body是object类型，文件信息解析到c.files
 *       application/x-www-form-urlencoded 传统的表单类型，c.body是object类型，用于获取提交的表单数据。
 *       text/* c.body 是文本类型，c.body=c.rawBody.toString('UTF-8').
 *       其他类型： c.body是buffer类型，就是对c.rawBody的调用
 */